package com.countertack.testcases;

import java.net.InetAddress;
import java.util.UUID;

import org.json.JSONArray;
import org.json.JSONObject;

import com.countertack.impala.ImpalaConnector;
import com.countertack.ssh.SSHManager;
import com.countertack.utils.Configuration;
import com.countertack.utils.HttpClientUtils;
import com.countertack.utils.Utils;
import com.countertack.vmware.VMWareConnector;
import com.countertack.vmware.VMWareUtils;
import com.vmware.vim25.mo.VirtualMachine;

public class VerifyingUnsupportedPatchSetAPI {

	public static void main(String[] args) throws Exception {
		StringBuffer testCaseResult = new StringBuffer();
		ImpalaConnector iConnector = null;
		VMWareConnector esxiConnector = null;
		try {

		if (args.length <= 0) {

				System.out.println("configuration details missed !");
				return;
			}
			String configFilePath = args[0];

		 /*String configFilePath =
			"C:\\Users\\user\\Desktop\\smoketestautomation\\config.properties";*/
			// String configFilePath = "config.properties";
			String uuid = UUID.randomUUID().toString();
			Configuration.loadProperties(configFilePath);

			String vmUser = Configuration.getProperty("vmuser");
			String vmPassword = Configuration.getProperty("vmpassword");
			iConnector = new ImpalaConnector();
			iConnector.createImpalaConnection(Configuration
					.getProperty("sentinelehost"));

			InetAddress address = InetAddress.getByName(Configuration
					.getProperty("sentinelehost"));
			String sentenelIp = address.getHostAddress();
			System.out.println(address.getHostAddress());
			// connect to esxi and starting virtual machines

			esxiConnector = new VMWareConnector(
					Configuration.getProperty("esxi"));
			// poweredOn
			VirtualMachine endPointMachine = esxiConnector
					.getVirtualMachineByname(Configuration
							.getProperty("vmname"));

			// win7x64-sym-2
			System.out.println("power state >>>"
					+ endPointMachine.getRuntime().powerState);

			// System.out.println("VM Ip Address>>>" + vmIp);
			String smokeSnapShotName = Configuration
					.getProperty("rootsnapshotname");
			esxiConnector.revertToSnapShort(endPointMachine.getSnapshot()
					.getRootSnapshotList(), smokeSnapShotName);

			System.out.println("Reverting to root snap shot>>>>>"
					+ smokeSnapShotName);

			esxiConnector.checkAndRunVirtualMachine(endPointMachine);

			String vmIp = Configuration.getProperty("vmip");
			if (vmIp == null || vmIp.trim() == "") {

				vmIp = endPointMachine.getGuest().ipAddress;
			}
			System.out.println("ip>>>" + endPointMachine.getGuest().ipAddress);

			SSHManager endpointSsh = new SSHManager(vmUser, vmPassword, vmIp);
			endpointSsh.connect();
			testCaseResult.append("VM NAME>>>>"
					+ Configuration.getProperty("vmname") + "\n");
			testCaseResult.append("VM IP>>>"
					+ endPointMachine.getGuest().ipAddress + "\n");
			testCaseResult.append("Sentinel  IP>>>" + sentenelIp + "\n");

			// installing agent

			boolean isXp = false;
			boolean is32bit = false;

			String osType = VMWareUtils.getVMOSArchitecture(
					Configuration.getProperty("esxi"),
					Configuration.getProperty("vmname"));
			if (osType != null) {

				osType = osType.toLowerCase();

				if (osType.contains("xp")) {

					isXp = true;
				} else if (osType.contains("32")) {

					is32bit = true;

				}

			}

			Utils.InstallKernalModuleOnEndpointmachine(endpointSsh, vmUser,
					sentenelIp, isXp);

			// retriving endpoint id
			String eId = null;
			try {
				eId = Utils.getUnsupportedEndpointId(iConnector, vmIp);
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Unable to install endpoint ");
				return;
			}

			if (eId == null) {

				System.out.println("endpoint  installed suscess fully");
				eId = Utils.getDriverVersion(eId, iConnector);
				testCaseResult.append("Endpoint ID>>>>" + eId + "\n");
				String kernal_module_version = Utils.getDriverVersion(eId,
						iConnector);
				testCaseResult.append("Kernal Module Version>>>>"
						+ kernal_module_version + "\n");
				return;
			}

			testCaseResult.append("Endpoint ID>>>>" + eId + "\n");

			String kernal_module_version = Utils.getDriverVersion(eId,
					iConnector);
			testCaseResult.append("Kernal Module Version>>>>"
					+ kernal_module_version + "\n");

			String tcpIp = Utils.getTcpIPSymbol(endpointSsh);
			if (tcpIp != null) {
				tcpIp = tcpIp.toLowerCase();
			}

			System.out.println("TCPIP Symbol>>>" + tcpIp);
			testCaseResult.append("TCPIP Symbol>>>>" + tcpIp + "\n");
			String ntos = Utils.getNtosKrnlSymbol(endpointSsh);
			if (ntos != null) {

				ntos = ntos.toLowerCase();
			}

			System.out.println("NTOS Symbol>>>>" + ntos);
			testCaseResult.append("NTOS Symbol>>>>" + ntos + "\n");
			String ntoslpa = null;
			if (is32bit || isXp) {

				ntoslpa = Utils.getNtosKrnlpaSymbol(endpointSsh);
				if (ntoslpa != null) {

					ntoslpa = ntoslpa.toLowerCase();
				}
				System.out.println("NTOSLPA Symbol>>>>" + ntoslpa);
				testCaseResult.append("NTOSLPA Symbol>>>>" + ntoslpa + "\n");

			}

			// verifying unsupported patchset list from api

			String getRes = HttpClientUtils.get(Configuration
					.getProperty("restapirooturi")
					+ "/reports/unsupported_endpoints/run/");

			if (getRes == null) {

				System.out
						.println("Unable to retrive unsupported endpoints list");
				testCaseResult
						.append("Unable to retrive unsupported endpoints list"
								+ "\n");
				return;

			}

			JSONObject unsupportedEndpoints = new JSONObject(getRes);
			if (unsupportedEndpoints.isNull("rows")) {

				System.out
						.println("Unsupported patch set endpoints are not available");
				testCaseResult
						.append("Unsupported patch set endpoints are not available"
								+ "\n");
				return;

			}
			JSONArray rows = unsupportedEndpoints.optJSONArray("rows");
			String endPointId = null;
			String unsSymbolTcpIp = null;
			String unsSymbolNtos = null;

			for (int i = 0; i < rows.length(); i++) {

				JSONArray unsupportedItem = rows.optJSONArray(i);

				for (int j = 0; j < unsupportedItem.length(); j++) {

					JSONObject information = unsupportedItem.optJSONObject(j);
					if (!information.isNull("table")) {

						String table = information.optString("table");

						if (table.equalsIgnoreCase("endpoints")) {

							if (!information.isNull("object")) {
								JSONObject endpDetails = information
										.optJSONObject("object");
								endPointId = endpDetails.optString("id");
								unsSymbolTcpIp = endpDetails.optString("tcpip");
								unsSymbolNtos = endpDetails.optString("nt");

							}

						} /*
						 * else if (table.equalsIgnoreCase("meta")) { if
						 * (!information.isNull("object")) { JSONObject metaInf
						 * = information .optJSONObject("object"); unsSymbol =
						 * metaInf.optString("patchset"); }
						 * 
						 * }
						 */
					}

				}

				if (eId.equalsIgnoreCase(endPointId)) {
					testCaseResult.append("Unsupported Symbol TcpIp>>>>"
							+ unsSymbolTcpIp + "\n"
							+ "Unsupported Symbol NTOS>>>>" + unsSymbolNtos
							+ "\n");
					break;
				}

			}

			if (eId.equalsIgnoreCase(endPointId)) {

				System.out
						.println("Verifying unsupported patchset endpoints list from API---------->Pass");
				testCaseResult
						.append("Verifying unsupported patchset endpoints list from API---------->Pass"
								+ "\n");

			} else {
				System.out
						.println("Verifying unsupported patchset endpoints list from API---------->Fail");
				testCaseResult
						.append("Verifying unsupported patchset endpoints list from API---------->Fail"
								+ "\n");
				return;
			}

			if (unsSymbolTcpIp != null) {

				if (tcpIp.contains(unsSymbolTcpIp)) {

					System.out
							.println("Verifying unsupported symbol from API---------->Pass");
					testCaseResult
							.append("Verifying unsupported symbol from API---------->Pass"
									+ "\n");
					System.out.println("Symbol-Type_Symbol" + "::" + "TCPIP_"
							+ unsSymbolTcpIp + "\n");
					testCaseResult.append("Symbol-Type_Symbol" + "::"
							+ "TCPIP_" + unsSymbolTcpIp + "\n");

				}

			}
			if (unsSymbolNtos != null) {

				if (ntos.contains(unsSymbolNtos)) {

					System.out
							.println("Verifying unsupported symbol from API---------->Pass");
					testCaseResult
							.append("Verifying unsupported symbol from API---------->Pass"
									+ "\n");
					System.out.println("Symbol-Type_Symbol" + "::" + "NTOS_"
							+ unsSymbolNtos + "\n");
					testCaseResult.append("Symbol-Type_Symbol" + "::" + "NTOS_"
							+ unsSymbolNtos + "\n");

				} else if (ntoslpa != null && ntoslpa.contains(unsSymbolNtos)) {

					System.out
							.println("Verifying unsupported symbol from API---------->Pass");
					testCaseResult
							.append("Verifying unsupported symbol from API---------->Pass"
									+ "\n");
					System.out.println("Symbol-Type_Symbol" + "::" + "NTOS_"
							+ unsSymbolNtos + "\n");
					testCaseResult.append("Symbol-Type_Symbol" + "::" + "NTOS_"
							+ unsSymbolNtos + "\n");

				}

			}
			if (unsSymbolNtos == null && unsSymbolNtos == null) {

				System.out
						.println("Verifying unsupported symbol from API---------->Fail");
				testCaseResult
						.append("Verifying unsupported symbol from API---------->Fail"
								+ "\n\n\n\n\n");

			}

			// verifying unsupported endpoint details

			testCaseResult
					.append("<=================Verifying Unsupported Endpoint Details==============> "
							+ "\n\n");

			String endpointDetails = HttpClientUtils.get(Configuration
					.getProperty("restapirooturi") + "/endpoints/" + eId);

			try {
				if (endpointDetails != null) {
					testCaseResult.append("Endpoint details from api>>>"
							+ endpointDetails + "\n");
					JSONObject endpointDetaObj = new JSONObject(endpointDetails);

					if (endpointDetaObj.optString("num_cpus") != null) {

						testCaseResult
								.append("Verifying num_cpus>>>Pass  ### num_cpus val>>>"
										+ endpointDetaObj.optString("num_cpus")
										+ "\n");
						System.out
								.println("Verifying num_cpus>>>Pass  ### num_cpus val>>>"
										+ endpointDetaObj.optString("num_cpus")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying num_cpus>>>Fail  ### num_cpus val>>>"
										+ endpointDetaObj.optString("num_cpus")
										+ "\n");

						System.out
								.println("Verifying num_cpus>>>Fail  ### num_cpus val>>>"
										+ endpointDetaObj.optString("num_cpus")
										+ "\n");

						// memory

					}

					if (endpointDetaObj.optString("memory") != null) {

						testCaseResult
								.append("Verifying memory>>>Pass  ### memory val>>>"
										+ endpointDetaObj.optString("memory")
										+ "\n");
						System.out
								.println("Verifying memory>>>Pass  ### memory val>>>"
										+ endpointDetaObj.optString("memory")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying memory>>>Fail  ### memory val>>>"
										+ endpointDetaObj.optString("memory")
										+ "\n");
						System.out
								.println("Verifying memory>>>Fail  ### memory val>>>"
										+ endpointDetaObj.optString("memory")
										+ "\n");

					}

					if (endpointDetaObj.optString("mac") != null) {

						testCaseResult
								.append("Verifying mac>>>Pass  ### mac val>>>"
										+ endpointDetaObj.optString("mac")
										+ "\n");
						System.out
								.println("Verifying mac>>>Pass  ### mac val>>>"
										+ endpointDetaObj.optString("mac")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying mac>>>Fail  ### mac val>>>"
										+ endpointDetaObj.optString("mac")
										+ "\n");
						System.out
								.println("Verifying mac>>>Fail  ### mac val>>>"
										+ endpointDetaObj.optString("mac")
										+ "\n");

					}

					if (endpointDetaObj.optString("cpu_type") != null) {

						testCaseResult
								.append("Verifying cpu_type>>>Pass  ### cpu_type val>>>"
										+ endpointDetaObj.optString("cpu_type")
										+ "\n");
						System.out
								.println("Verifying cpu_type>>>Pass  ### cpu_type val>>>"
										+ endpointDetaObj.optString("cpu_type")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying cpu_type>>>Fail  ### cpu_type val>>>"
										+ endpointDetaObj.optString("cpu_type")
										+ "\n");
						System.out
								.println("Verifying cpu_type>>>Fail  ### cpu_type val>>>"
										+ endpointDetaObj.optString("cpu_type")
										+ "\n");

					}

					if (endpointDetaObj.optString("ip") != null) {

						testCaseResult
								.append("Verifying ip>>>Pass  ### ip val>>>"
										+ endpointDetaObj.optString("ip")
										+ "\n");
						System.out.println("Verifying ip>>>Pass  ### ip val>>>"
								+ endpointDetaObj.optString("ip") + "\n");

					} else {

						testCaseResult
								.append("Verifying ip>>>Fail  ### ip val>>>"
										+ endpointDetaObj.optString("ip")
										+ "\n");
						System.out.println("Verifying ip>>>Fail  ### ip val>>>"
								+ endpointDetaObj.optString("ip") + "\n");

					}

					if (endpointDetaObj.optString("domain") != null) {

						testCaseResult
								.append("Verifying domain>>>Pass  ### domain val>>>"
										+ endpointDetaObj.optString("domain")
										+ "\n");
						System.out
								.println("Verifying domain>>>Pass  ### domain val>>>"
										+ endpointDetaObj.optString("domain")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying domain>>>Fail  ### domain val>>>"
										+ endpointDetaObj.optString("domain")
										+ "\n");
						System.out
								.println("Verifying domain>>>Fail  ### domain val>>>"
										+ endpointDetaObj.optString("domain")
										+ "\n");

					}

					if (endpointDetaObj.optString("product_name") != null) {

						testCaseResult
								.append("Verifying product_name>>>Pass  ### product_name val>>>"
										+ endpointDetaObj
												.optString("product_name")
										+ "\n");
						System.out
								.println("Verifying product_name>>>Pass  ### product_name val>>>"
										+ endpointDetaObj
												.optString("product_name")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying product_name>>>Fail  ### product_name val>>>"
										+ endpointDetaObj
												.optString("product_name")
										+ "\n");
						System.out
								.println("Verifying product_name>>>Fail  ### product_name val>>>"
										+ endpointDetaObj
												.optString("product_name")
										+ "\n");

					}

					if (endpointDetaObj.optString("name") != null) {

						testCaseResult
								.append("Verifying name>>>Pass  ### name val>>>"
										+ endpointDetaObj.optString("name")
										+ "\n");

						System.out
								.println("Verifying name>>>Pass  ### name val>>>"
										+ endpointDetaObj.optString("name")
										+ "\n");

					} else {

						testCaseResult
								.append("Verifying name>>>Fail  ### name val>>>"
										+ endpointDetaObj.optString("name")
										+ "\n");
						System.out
								.println("Verifying name>>>Fail  ### name val>>>"
										+ endpointDetaObj.optString("name")
										+ "\n");

					}

				} else {
					testCaseResult
							.append("Unable to verify endpoint details because of no values  return from endpoints api values are >>>"
									+ endpointDetails + "\n");
					System.out
							.println("Unable to verify endpoint details because of no values  return from endpoints api values are >>>"
									+ endpointDetails + "\n");
					System.out
							.println("Unable to verify endpoint details because of no values  return from endpoints api values are >>>"
									+ endpointDetails + "\n");

				}

			} catch (Exception e) {
				testCaseResult
						.append("Unable to verify endpoint details because of invalid values  return from endpoints api values are >>>"
								+ endpointDetails + "\n");
				System.out
						.println("Unable to verify endpoint details because of invalid values  return from endpoints api values are >>>"
								+ endpointDetails + "\n");

			}

		} finally {

			try {
				if (iConnector != null) {
					iConnector.closeImpalaConnection();
				}
			} catch (Exception e) {

				e.printStackTrace();
			}

			try {
				if (esxiConnector != null) {

					esxiConnector.closeEsxiConnection();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			Utils.addResultsToLog(testCaseResult,
					"verifying_unsupported_patchset_api",
					Configuration.getProperty("vmname"));
		}

	}
}
